Mybatis 연동하기

✒️ 2025-05-28 12:56 내용 수정


환경설정

  1. Annotation 기반 설정 파일#프로젝트 설정에서 필요한 설정을 미리 준비한다.
    • pom.xml 파일, config 패키지의 클래스들(RootContext, ServletContext, WebInitializer)
    • web.xml, servlet-context.xml, root-context.xml 삭제
  2. src/main/resources에 context 패키지를 만들어 RootContext 파일을 옮긴다.
  3. RootContext 파일을 총 3개로 복사해서 각각의 이름을 Context_1_dataSource, Context_2_myBatis, Context_3_dao로 변경한다.
    • Context_1_dataSource, Context_2_myBatis : 외부에서 온 라이브러리의 클래스들 객체로 만듦
    • Context_3_dao : DB 접속 시 사용할 DAO 객체
  4. src/main/resources에 config 패키지를 만들어 WebInitializer 클래스를 옮긴다.
  5. src/main/resources에 mvc 패키지를 만들어 ServletContext 클래스를 옮긴다.

spring mybatis.png

  1. WebInitializer에서 getRootConfigClasses() 메소드의 반환값을 Context_1_dataSource.class, Context_2_myBatis.class, Context_3_dao.class로 수정한다.

spring mybatis 4.png

  1. oraclexe/app/oracle/product/11.2.0/server/jdbc/lib에서 ojdbc6.jar를 복사해서 apache-tomcat/lib에 붙여 넣는다.

spring mybatis 2.png
spring mybatis 3.png

  1. src/main/resources에 config.mybatis 패키지를 만들고, mybatis-config.xml 파일을 넣는다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "HTTP://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
	<settings>
		<setting name="cacheEnabled" value="false" />
		<setting name="useGeneratedKeys" value="true" />
		<setting name="defaultExecutorType" value="REUSE" />
	</settings>

	<!-- 별칭 등록 -->
	<typeAliases>
		<typeAlias type="package.className" alias="별칭"/>
	</typeAliases>
	
	<mappers>
		<mapper resource="config/mybatis/mapper/mapperName.xml" />
	</mappers>
</configuration>
  1. config.mybatis 패키지에 config.mybatis.mapper 패키지를 만들고, mapper 파일을 넣는다.
    • 필요한 내용에 따라 수정해서 사용
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="namespace">
	<select id="id" resultType="package.returnType">
		select * from tableName
	</select>
</mapper>

spring mybatis 5.png

  1. https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp 에 접속해서 1.4 버전을 선택하고, Maven 항목을 복사해서 pom.xml파일의 dependencies에 추가한다.

spring mybatis 6.png

<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>

spring mybatis 7.png

  1. Context_1_dataSource에 DataSource 객체를 추가한다.
@Bean
public DataSource ds() {
	BasicDataSource ds = new BasicDataSource();
	ds.setDriverClassName("oracle.jdbc.OracleDriver");
	ds.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
	ds.setUsername("계정명");
	ds.setPassword("비밀번호");
	return ds;
}
  1. https://mvnrepository.com/artifact/org.mybatis/mybatis 에 접속해서 Mybatis 3.5.6 버전의 Maven을 복사해서 pom.xml 파일의 dependencies에 추가한다.

spring mybatis 9.png

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
</dependency>

spring mybatis 8.png

  1. https://mvnrepository.com/artifact/org.mybatis/mybatis-spring 에서 1.3.1 버전의 Maven을 복사해 pom.xml의 dependencies에 추가한다.

spring mybatis 10.png

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
</dependency>

spring mybatis 11.png

  1. https://mvnrepository.com/artifact/org.springframework/spring-jdbc 에서 spring과 동일한 버전의 jdbc를 찾아 Maven 항목을 복사해 pom.xml에 추가한다.
    • 실습에서 사용한 spring은 5.1.20 버전이어서 해당 버전으로 받아 사용했다.

spring mybatis 12.png

<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>

spring mybatis 13.png

  1. Context_2_myBatis 클래스에서 DI를 통해 Datasource를 받고, SqlSessionFactory 객체를 Bean 객체로 생성한다.
import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration
@RequiredArgsConstructor
public class Context_2_myBatis {

	// 생성자 주입 - lombok의 @RequiredArgsConstructor로 지정
	final DataSource ds;
	
	@Bean
	public SqlSessionFactory factoryBean() throws Exception{
		SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
		
		factoryBean.setDataSource(ds);
		
		// mapper를 알고있는 mybatis-config.xml 파일의 위치를 알려줘야 함
		factoryBean.setConfigLocation(new ClassPathResource("config/mybatis/mybatis-config.xml"));
		
		return factoryBean.getObject();
	}

	@Bean
	public SqlSessionTemplate sqlSessionBean() throws Exception {
		return new SqlSessionTemplate(factoryBean());
	}
}

Mybatis Spring

  1. SqlSessionFactoryBean
    • SqlSessionFactoryBean은 Spring의 FactoryBean 인터페이스를 구현한다.
    • Spring이 SqlSessionFactoryBean 자체를 생성하는게 아닌 Factory에서 getObject() 메소드를 호출한 결과를 리턴한다.
    • Spring은 어플리케이션 시작 지점에 SqlSessionFactory를 빌드하고, SqlSessionFactory라는 이름으로 저장한다.
  2. JSP에서 사용했던 Mybatis와의 차이점
    • Mybatis에서는 SqlSession 객체를 생성하기 위해 SqlSessionFactory 객체를 사용한다.
    • Mybatis Spring에서는 연동 모듈을 사용하면 SqlSessionFactory를 직접 사용할 필요가 없는데, Spring 트랜잭션 설정에 따라 자동으로 commit 또는 rollback을 수행하고 닫는 thread-safe SqlSession 객체가 Spring Bean에 주입되기 때문이다.
    • SqlSessionTemplate 클래스는 SqlSession를 구현하고 코드에서 sqlSession을 대체하는 역할을 한다.
    • SQL을 처리하는 Mybatis Method를 호출할 때 SqlSessionTemplate은 SqlSession이 현재 Spring transaction에 사용될 수 있도록 보장한다.
    • SqlSessionTemplate은 필요한 시점에 Session을 닫고, commit하거나 rollback하는 것을 포함한 SqlSession의 라이프사이클을 관리한다.

DB에서 데이터 조회하기

spring mybatis flow.png

  1. 연동을 마친 상태에서 src/main/resources에 dto 패키지를 만들고, EmployeesDTO 클래스를 만든다.
package dto;

import lombok.Data;

@Data
public class EmployeesDTO {
	private int employee_id;
	private String first_name;
	private String last_name;
	private String email;
	private String phone_number;
	private String job_id;
	private int salary;
}
  1. src/main/resources에 dao 패키지를 만들고, EmployeesDAO 클래스를 만든다.
package dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import dto.EmployeesDTO;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class EmployeesDAO {

	final SqlSession sqlSession;
	
	// 전체 사원 조회
	public List<EmployeesDTO> selectList() {
		List<EmployeesDTO> list = sqlSession.selectList("employees.employees_list");
		return list;
	}
}	
  1. Context_3_dao 클래스에 dao bean을 만든다.
package context;

import org.apache.ibatis.session.SqlSession;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import dao.EmployeesDAO;

@Configuration
public class Context_3_dao {

	@Bean
	public EmployeesDAO dao(SqlSession sqlSession) {
		return new EmployeesDAO(sqlSession);
	}
}
  1. mapper 파일에 SQL을 작성한다.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="employees">

	<select id="employees_list" resultType="employees">
		select * from employees
	</select>
</mapper>
  1. mybatis-config.xml 파일에서 mapper 이름과 기타 설정이 맞는지 확인하여 수정한다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "HTTP://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
	<settings>
		<setting name="cacheEnabled" value="false" />
		<setting name="useGeneratedKeys" value="true" />
		<setting name="defaultExecutorType" value="REUSE" />
	</settings>
	
	<typeAliases>
		<typeAlias type="dto.EmployeesDTO" alias="employees"/>
	</typeAliases>
	
	<mappers>
		<mapper resource="config/mybatis/mapper/employees.xml" />
	</mappers>
</configuration>
  1. src/main/java의 프로젝트 패키지에 EmployeesController 클래스를 만든다.
package com.nogroup.db;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import dao.EmployeesDAO;
import dto.EmployeesDTO;
import lombok.RequiredArgsConstructor;

@Controller
@RequiredArgsConstructor
public class EmployeesController {
	
	public static final String VIEW_PATH = "/WEB-INF/views/";
	
	final EmployeesDAO employees_dao;
	
	@RequestMapping(value= {"/","list"})
	public String list(Model model) {
		List<EmployeesDTO> list = employees_dao.selectList();
		
		model.addAttribute("list", list);
		return VIEW_PATH+"employees_list.jsp";
	}
}
  1. Controller 객체를 만들기 위해 ServletContext에 Bean을 추가한다.
package mvc;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.nogroup.db.EmployeesController;

import dao.EmployeesDAO;

@Configuration
@EnableWebMvc
//@ComponentScan("com.nogroup.db") // 수동 Bean 생성을 위해 주석
public class ServletContext implements WebMvcConfigurer{
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
	}
//	
//	@Bean
//	public InternalResourceViewResolver resolver() {
//		InternalResourceViewResolver resolver = new InternalResourceViewResolver();
//		resolver.setViewClass(JstlView.class);
//		resolver.setPrefix("/WEB-INF/views/");
//		resolver.setSuffix(".jsp");
//		return resolver;
//	}
	
	@Bean
	public EmployeesController empleController(EmployeesDAO employees_dao) {
		return new EmployeesController(employees_dao);
	}
}
  1. src/main/webapp/WEB-INF/views에 employees_list.jsp를 생성한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<table border="1">
		<tr>
			<th>사번</th>
			<th>이름</th>
			<th>성</th>
			<th>이메일</th>
			<th>전화번호</th>
			<th>직무</th>
			<th>급여</th>
		</tr>
		
		<c:forEach var="dto" items="${list}">
		<tr>
			<th>${dto.employee_id}</th>
			<th>${dto.first_name}</th>
			<th>${dto.last_name}</th>
			<th>${dto.email}</th>
			<th>${dto.phone_number}</th>
			<th>${dto.job_id}</th>
			<th>${dto.salary}</th>
		</tr>
		</c:forEach>
	</table>
</body>
</html>

spring mybatis 14.png